package xyz.eden.cloud.common.web.tool;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * IP 工具
 *
 * @author gavin
 * @version 1.0
 * @descriptor
 * @date 2023/3/10 14:52
 */
@Slf4j
public final class IpTool {

    private static final String X_FORWARDED_FOR = "X-Forwarded-For";
    private static final String X_REAL_IP = "X-Real-IP";

    private IpTool() {
    }

    /**
     * 获取客户端IP
     * 优先级：X-Real-IP > X-Forwarded-For > $remote_addr
     */
    public static String getRemoteRealIp(HttpServletRequest request) {

        String ipAddress = getIpAddress(request);
        log.info("IpAddress: [{}]", ipAddress);

        String realIp = request.getHeader(X_REAL_IP);
        if (StringUtils.isNotBlank(realIp)) {
            return realIp;
        }

        return getRemoteIpAddress(request);
    }

    /**
     * 获取Ip地址
     *
     * @param request
     * @return
     */
    private static String getIpAddress(HttpServletRequest request) {
        String Xip = request.getHeader(X_REAL_IP);
        String XFor = request.getHeader(X_FORWARDED_FOR);
        if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = XFor.indexOf(",");
            if (index != -1) {
                return XFor.substring(0, index);
            } else {
                return XFor;
            }
        }
        XFor = Xip;
        if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
            return XFor;
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getRemoteAddr();
        }
        return XFor;
    }

    /**
     * 获取远程客户端的IP
     *
     * @param request
     * @return
     */
    public static String getRemoteIpAddress(HttpServletRequest request) {
        String rip = request.getRemoteAddr();
        String xff = request.getHeader(X_FORWARDED_FOR);
        String ip = "";
        if (xff != null && xff.length() != 0) {
            // 处理多级代理的情况
            int px = xff.indexOf(',');
            if (px != -1) {
                ip = xff.substring(0, px);
            } else {
                ip = xff;
            }
        } else {
            ip = rip;
        }
        return ip.trim();
    }

    public static boolean isIPv6(String ipAddress) {
        boolean isIPv6 = false;

        if (ipAddress != null) {
            try {
                InetAddress inetAddress = InetAddress.getByName(ipAddress);
                isIPv6 = (inetAddress instanceof Inet6Address);
            } catch (UnknownHostException ex) {
                log.warn("不能解析的IP地址:{}", ipAddress);
            }
        }
        return isIPv6;
    }
}
